<template>
  <div class="employees-container">
    <div class="app-container">
      <!-- 头部导航条 -->
      <PageTools>

        <template #left> 共{{ total }}条记录 </template>

        <template #right>
          <el-button type="info" size="small" @click="exportExcelMore">多表头excel导出</el-button>
          <el-button v-if="checkBtnAccess('EXCEL_EXPORT')" type="danger" size="small" @click="exportExcel">普通excel导出</el-button>
          <el-button v-if="checkBtnAccess('EXCEL_IMPORT')" type="success" size="small" @click="$router.push('/improt')">excel导入</el-button>
          <el-button v-if="checkBtnAccess('USER_ADD')" type="primary" size="small" @click="isShow=true">新增员工</el-button>
        </template>

      </PageTools>

      <!-- 员工信息表格 -->
      <el-card v-loading="loading" style="margin-top: 10px;">
        <el-table border :data="list">
          <el-table-column label="序号" sortable type="index" :index="indexMethod" />
          <el-table-column label="姓名" sortable prop="username" />
          <el-table-column label="员工头像" align="center">
            <!-- 插槽 -->
            <template #default="{row}">
              <img
                v-imagerror="require('@/assets/common/bigUserHeader.png')"
                :src="row.staffPhoto || defaultImg"
                class="staff-photo"
                @click="handleShowCode(row.staffPhoto)"
              >
            </template>
          </el-table-column>
          <el-table-column label="手机号" sortable prop="mobile" />
          <el-table-column
            label="工号"
            sortable
            prop="workNumber"
          />
          <el-table-column label="聘用形式" sortable prop="formOfEmployment" :formatter="formatEmployment" />
          <el-table-column label="部门" sortable prop="departmentName" />
          <el-table-column label="入职时间" sortable prop="timeOfEntry">
            <template #default="{row}">
              {{ row.timeOfEntry | formatDate }}

            </template>
          </el-table-column>
          <el-table-column label="操作" fixed="right" width="280">
            <template #default="{row}">
              <el-button v-if="checkBtnAccess('USER_EDIT')" type="text" size="small" @click="$router.push(`/employees/detail/${row.id}`)">查看</el-button>
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="handleRoleAssign(row.id)">角色</el-button>
              <el-button v-if="checkBtnAccess('USER_DEL')" type="text" size="small" @click="del(row.id)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <div style="height: 60px; margin-top: 10px">
          <el-pagination
            :current-page="page"
            :page-sizes="[5, 10, 15, 20]"
            :page-size="5"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </el-card>

      <!-- 新增员工组件弹窗 -->
      <AddEmployee :show-dialog.sync="isShow" @add-employee="addEmployee" />

      <!-- 展示头像弹窗（二维码） -->
      <el-dialog
        title="员工头像展示"
        :visible="showImgDialog"
        width="400px"
        @close="showImgDialog=false"
      >
        <div style="text-align: center;">
          <!-- 绘制二维码的画布 -->
          <canvas ref="staffCanvas" />
        </div>
      </el-dialog>

      <!-- 分配角色的组件 -->
      <!-- <el-button type="text" size="small" ">角色</el-button> -->
      <AssignRole :show-role-dialog.sync="showRoleDialog" :user-id="userId" />
    </div>
  </div>
</template>

<script>
import { reqGetUserList, delEmployee } from '@/api/employees' // 获取员工信息的接口  删除接口
import hiretype from '@/api/constant/employees' // 枚举
import AddEmployee from './compoents/add-employees.vue' // 新增员工组件
import dayjs from 'dayjs'
import employees from '@/api/constant/employees' // 枚举
import QRCode from 'qrcode' // 打印
import AssignRole from './compoents/assign-role.vue' // 分配角色的组件
export default {
  components: {
    AddEmployee,
    AssignRole
  },
  data() {
    return {
      list: [], // 员工的信息数据
      page: 1, // 获取的页码
      size: 5, // 获取的条数
      total: 0, // 总条数
      loading: false, // 加载圈
      isShow: false, // 控制新增员工组件
      defaultImg: 'https://hrsass-49-cs-1312445828.cos.ap-shanghai.myqcloud.com/01.jpg', // 默认员工头像
      showImgDialog: false, // 控制头像弹窗
      showRoleDialog: false, // 用于控制角色对话框的显示和隐藏
      userId: '' // 分配角色使用的用户id
    }
  },
  created() { // 获取员工的方法
    this.getUserList()
  },
  methods: {
    async getUserList() { // 获取员工的方法
      this.loading = true
      const res = await reqGetUserList(this.page, this.size)
      this.total = res.total // 总条数
      this.list = res.rows // 员工的信息数据
      this.loading = false
    },
    handleSizeChange(val) { // 点击每页多少条触发
      this.size = val
      this.getUserList()
    },
    handleCurrentChange(val) { // 当前的页码
      this.page = val
      this.getUserList()
    },
    indexMethod(index) { // 自定义序号
      return index + 1 + (this.page - 1) * this.size
    },
    formatEmployment(row, column, cellValue, index) { // 格式化  枚举
      const res = hiretype.hireType.find(item => item.id === +cellValue)
      return res ? res.value : '未知员工'
    },
    del(id) { // 删除员工
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        this.$message({
          type: 'success',
          message: '删除成功!'
        })
        if (this.list.length === 1 && this.page > 1) {
          this.page--
        }
        // 删除当前
        await delEmployee(id)
        // 重新更新页面数据
        this.getUserList()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    addEmployee() { // 子组件的事件
      console.log(11)
      this.getUserList() // 获取员工的方法
    },
    // 7. 批量导出员工到excel表格中
    async exportExcel() {
      // 7.1 获取所有的员工数据
      const { rows } = await reqGetUserList(1, this.total)
      // 7.2 表头和中英文对照表
      const headersArr = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']
      const headersRelations = {
        '姓名': 'username',
        '手机号': 'mobile',
        '入职日期': 'timeOfEntry',
        '聘用形式': 'formOfEmployment',
        '转正日期': 'correctionTime',
        '工号': 'workNumber',
        '部门': 'departmentName'
      }

      // 7.3 把对象数组转成二维数组
      const data = this.formatFn(headersArr, headersRelations, rows)
      // console.log(data)

      // 7.4 导出excel
      import('@/vendor/Export2Excel').then(excel => {
        excel.export_json_to_excel({
          header: headersArr,
          data,
          filename: `${dayjs(new Date()).format('YYYY-MM-DD')}-员工信息表`,
          autoWidth: true,
          bookType: 'xlsx'
        })
      })
    },
    // 8. 把对象数组转成二维数组
    // [{}, {}, {}] => [[], [], []]
    formatFn(headersArr, headersRelations, rows) {
      // console.log(headersArr, headersRelations, rows)
      // 8.1 创建大的数组
      const outerArr = []

      // 8.2 遍历对象数组
      rows.forEach(item => {
        // 8.2.1 创建一个小的数组
        const innerArr = []

        // 8.2.2 遍历表头, 依次从对象中取出值放入小的数组
        headersArr.forEach(key => {
          // 8.2.3 根据中文键取出英文键
          const englishKey = headersRelations[key]

          // 8.2.4 取出内容
          let value = item[englishKey]

          // 8.2.5 判断键是否是 入职日期 和 转正日期
          if (['timeOfEntry', 'correctionTime'].includes(englishKey)) {
            value = dayjs(value).format('YYYY-MM-DD')
          }

          // 8.2.6 判断键是否是 聘用形式
          if (['formOfEmployment'].includes(englishKey)) {
            const { hireType } = employees
            // 注意注意: 服务器给过来的值(cellValue)是字符串, 但是(item.id)是数值
            const res = hireType.find(item => item.id === Number(value))
            value = res ? res.value : '未知工种'
          }

          // 8.2.5 根据英文键从对象中取出值
          innerArr.push(value)
        })

        // 8.2.2 把小的数组装入到大的数组中
        outerArr.push(innerArr)
      })

      // 8.3 返回大的数组
      return outerArr
    },
    // 9. 多表头导出
    async exportExcelMore() {
      const points = this.$store.getters.points
      if (points.includes('EXCEL_MU_EXPORT')) {
        // 9.1 获取所有的员工数据
        const { rows } = await reqGetUserList(1, this.total)
        // 9.2 表头/中英文对照表/多表头/合并数组
        const headersArr = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']
        const headersRelations = {
          '姓名': 'username',
          '手机号': 'mobile',
          '入职日期': 'timeOfEntry',
          '聘用形式': 'formOfEmployment',
          '转正日期': 'correctionTime',
          '工号': 'workNumber',
          '部门': 'departmentName'
        }
        const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
        const merges = ['A1:A2', 'B1:F1', 'G1:G2']

        // 7.3 把对象数组转成二维数组
        const data = this.formatFn(headersArr, headersRelations, rows)

        // 7.4 导出excel
        import('@/vendor/Export2Excel').then(excel => {
          excel.export_json_to_excel({
            header: headersArr,
            data,
            filename: `${dayjs(new Date()).format('YYYY-MM-DD')}-员工信息表`,
            autoWidth: true,
            bookType: 'xlsx',
            multiHeader, // 配置多表头
            merges // 配置单元格区域合并
          })
        })
      } else {
        this.$message.warning('穷b充点💴!')
        return
      }
    },
    handleShowCode(imgUrl) { // 点击员工头像的方法
      if (imgUrl) {
        console.log(imgUrl)
        // 打开弹窗
        this.showImgDialog = true
        // 生成二维码  用nextTick就可以获取数据更新后最新DOM的变化
        this.$nextTick(() => {
          QRCode.toCanvas(this.$refs.staffCanvas, imgUrl)
          console.log(this.$refs.staffCanvas.imgUrl)
        })
      } else {
        this.$message.warning('当前用户没有上传头像哦')
      }
    },
    handleRoleAssign(id) { // 点击角色触发
      this.showRoleDialog = true
      this.userId = id
    },
    checkBtnAccess(str) { // 按钮操作权
      const points = this.$store.getters.points
      return !!points?.includes(str)
    }
  }
}
</script>

<style lang='scss' scoped>
.employees-container {
  .staff-photo {
    width: 70px;
    height: 70px;
    border-radius: 50%;
  }
}
</style>
